#ifndef _CORE_H_
#define _CORE_H_
#include "os_config.h"
#include "type.h"

#define  __SCHEDULER_VERSION   "1.05"

#define  __WAIT_TICK_FOREVER   -1
#define  __RESUIT_OK        0
#define  __RESUIT_FAILED   -1
#define  __RESUIT_TIMEOUT  -2

#define   __TASK_STATUS_INIT           0x00
#define   __TASK_STATUS_STARTUP        0x01
#define   __TASK_STATUS_READY          0x02
#define   __TASK_STATUS_RUN            0x03
#define   __TASK_STATUS_STOP           0x04
#define   __TASK_STATUS_WAIT_TICK      0x05
#define   __TASK_STATUS_WAIT_SIGNAL    0x06
#define   __TASK_STATUS_WAIT_EVENT     0x07
#define   __TASK_STATUS_WAIT_MQ        0x08
#define   __TASK_STATUS_WAIT_ASYNC     0x09

#define   _TASK_PRIO_0   0u
#define   _TASK_PRIO_1   1u
#define   _TASK_PRIO_2   2u
#define   _TASK_PRIO_3   3u
#define   _TASK_PRIO_4   4u
#define   _TASK_PRIO_5   5u
#define   _TASK_PRIO_6   6u
#define   _TASK_PRIO_7   7u
#define   _TASK_PRIO_8   8u
#define   _TASK_PRIO_9   9u
#define   _TASK_PRIO_10  10u
#define   _TASK_PRIO_11  11u
#define   _TASK_PRIO_12  12u
#define   _TASK_PRIO_13  13u
#define   _TASK_PRIO_14  14u
#define   _TASK_PRIO_15  15u

typedef struct
{
    uint16_t line[_OS_CONFIG_CALL_SUBFUNC_DEPTH];
    uint8_t  count;
    uint8_t  quit;
} __line_t;

typedef  int32_t  __result_t;
typedef  struct __task*  task_t;
typedef void (*task_fn_t)(void);

void     __system_init(void);
void     __system_poll(void);
void     __tick_increase(void);
uint32_t __get_systick(void);

void  __set_idle_hook_func(void (idle_hook)(void));
__result_t  __task_create(const char* name, task_t* pt, task_fn_t fn, uint8_t mq_max, uint16_t mq_size,
                          uint8_t priority);
__result_t  __task_startup(task_t pt);
__result_t  __task_stop(task_t pt);
void       __task_exit(void);
void       __task_reset(void);
__line_t* __get_line(void);
void      __delay_tick(int tick);
void      __sleep_ms(int ms);
void      __signal_wait(__result_t* res, uint8_t set, int tick);
void      __signal_release(task_t pt);
void      __signal_clear(task_t pt);
void      __event_wait_and(__result_t* res, uint8_t set, uint32_t set_event, uint32_t* event, int tick);
void      __event_wait_or(__result_t* res, uint8_t set, uint32_t set_event, uint32_t* event, int tick);
void      __event_trigger(task_t pt, uint32_t event);
void      __event_clear(task_t pt);
#ifdef _OS_CONFIG_QUEUE_ENABLE
    void __mq_recv(__result_t* res, void* msg, int tick);
    __result_t __mq_send(task_t pt, void* msg, uint16_t size);
    void __mq_clear(task_t pt);
#endif

void    __async_wait(__result_t* result, uint8_t (*func)(void* arg), void* arg, int tick);
#if _OS_CONFIG_TASK_NAME_LENGTH
    const char* __get_task_name(task_t pt);
#endif

#ifndef  _OS_CONFIG_USE_MCU_C51
#define __TASK_FUNC(name)   task_t name;\
    static void _osTask_##name(void)
#else
#define __TASK_FUNC(name)   task_t name;\
    static void _osTask_##name(void)reentrant
#endif


#define __EXTERN_TASK_OBJECT(name) extern task_t name


#define __SYSTEM_INIT()         __system_init()
#define __SYSTEM_POLL()          __system_poll()
#define __TICK_INCREASE()       __tick_increase()

#if _OS_CONFIG_TASK_NAME_LENGTH
    #define __GET_TASK_NAME(pt)    __get_task_name(pt)
#endif

#define __GET_SYSTICK()        __get_systick()

#define __TASK_SWITCH          ptr->line[ptr->count]= (uint16_t)__LINE__;ptr->quit = 1;return; case __LINE__:
#define __TASK_BEGIN()        __line_t *ptr = __get_line();switch(ptr->line[ptr->count]){  case 0:
#define __TASK_END()          }
#define __CALL_SUB            ptr->line[ptr->count] = (uint16_t)__LINE__;ptr->line[ptr->count+1] = 0;case __LINE__:ptr->count++;
#define __CALL_END            if(ptr->quit)return;ptr->count--;
#define __TASK_CREATE(name,mq_max,mq_size,priority) __task_create(#name,&name,_osTask_##name,mq_max,mq_size,priority)

#define __TASK_STARTUP(name)  __task_startup(name)
#define __TASK_STOP(name)     __task_stop(name)
#define __TASK_EXIT()         __task_exit();return
#define __TASK_RESET()        __task_reset();return
#define __DELAY_TICK(tick)    __delay_tick(tick); __TASK_SWITCH
#define __SLEEP_MS(ms)        __sleep_ms(ms);__TASK_SWITCH
#define __SIGNAL_WAIT(result,tick) __signal_wait(NULL,1,tick);__TASK_SWITCH  __signal_wait(result,0,0)
#define __SIGNAL_RELEASE(name)     __signal_release(name)
#define __SIGNAL_CLEAR(name)       __signal_clear(name)
#define __EVENT_WAIT_AND(result,set,event,tick)  __event_wait_and(NULL,1,set,event,tick);__TASK_SWITCH __event_wait_and(result,0,set,event,tick)
#define __EVENT_WAIT_OR(result,set,event,tick)  __event_wait_or(NULL,1,set,event,tick);__TASK_SWITCH __event_wait_or(result,0,set,event,tick)
#define __EVENT_TRIGGER(name,event)             __event_trigger(name,event)
#define __EVENT_CLEAR(name)                     __event_clear(name)
#define __MQ_RECV(result,msg,tick)  __mq_recv(NULL,NULL,tick);__TASK_SWITCH  __mq_recv(result,msg,tick)
#define __MQ_SEND(name,msg,size)    __mq_send(name,msg,size)
#define __MQ_CLEAR(name)            __mq_clear(name)
#define __ASYNC_WAIT(result,func,arg,tick)  __async_wait(result,func,arg,tick); __TASK_SWITCH  __async_wait(result,NULL,NULL,0)
#define __SET_IDLE_HOOK_FUNC(IDLE_HOOK)     __set_idle_hook_func(IDLE_HOOK)
#endif /*_CORE_H_*/




